package modulelib

import (
	"errors"
	"net"
	"strconv"
	"time"

	uuid "github.com/satori/go.uuid"
	"github.com/wonderivan/logger"
)

//TCPServer TCP服务
type TCPServer struct {
	listener       net.Listener
	receiveEvent   func(key string, buffer []uint8)
	acceptEvent    func(key string)
	isRunning      bool
	isSignleAccept bool
	connMap        map[string]net.Conn
}

//Init 初始化TCP链接
func (_this *TCPServer) Init(ip string, port int, signleAccept bool) bool {
	_this.connMap = make(map[string]net.Conn)
	_this.isRunning = true
	_this.isSignleAccept = signleAccept
	return _this.listenPort(ip, port)
}

//Send TCP发送数据
func (_this *TCPServer) Send(key string, buffer []uint8) (int, error) {
	if _this.connMap == nil || !_this.isRunning {
		return 0, errors.New("未初始化")
	}
	conn, exit := _this.connMap[key]
	if exit && conn != nil {
		return conn.Write(buffer)
	}
	return 0, errors.New("对应Key的连接不存在")
}

//Close 关闭TCP链接
func (_this *TCPServer) Close() error {
	_this.isRunning = false
	if _this.connMap != nil {
		for _, v := range _this.connMap {
			if v != nil {
				v.Close()
			}
		}
	}
	_this.connMap = make(map[string]net.Conn)
	return _this.listener.Close()
}

//SetReceivEvent 设置接收回调函数
func (_this *TCPServer) SetReceivEvent(receiveEvent func(key string, buffer []uint8)) {
	_this.receiveEvent = receiveEvent
}

//SetAcceptEvent 设置接收回调函数
func (_this *TCPServer) SetAcceptEvent(acceptEvent func(key string)) {
	_this.acceptEvent = acceptEvent
}

//listenPort 监听端口
func (_this *TCPServer) listenPort(ip string, port int) bool {
	listener, err := net.Listen("tcp", ip+":"+strconv.Itoa(int(port)))
	_this.listener = listener
	//go _this.useBuffer()
	if err != nil {
		logger.Alert("server :: error listen:", err)
		return false
	}
	go func() {
		for _this.isRunning {
			if conn, err := _this.listener.Accept(); err != nil {
				logger.Alert("server :: accept error:", err)
				break
			} else {
				//为了不阻塞新的连接接入，采用协程接收与处理数据
				key := uuid.NewV4().String()
				_this.connMap[key] = conn
				if _this.acceptEvent != nil {
					_this.acceptEvent(key)
				}
				if _this.isSignleAccept {
					_this.receiceData(key)
				} else {
					go _this.receiceData(key)
				}
				//_this.conns.Push(conn)
			}
		}
	}()
	return true
}

//receiceData 循环接收数据，frameBuffer的生产者
func (_this *TCPServer) receiceData(key string) {
	if _this.connMap == nil || !_this.isRunning {
		logger.Debug("TCP未初始化")
		return
	}
	var buffer = make([]byte, 1024)
	var retryCount = 0
	conn, exit := _this.connMap[key]
	if !exit || conn == nil {
		return
	}
	defer func() {
		delete(_this.connMap, key)
		conn.Close()
	}()
	for _this.isRunning {
		if length, e := conn.Read(buffer); e != nil {
			if e.Error() == "EOF" {
				logger.Debug("读到EOF结束")
				retryCount = 0
				return
			}
			logger.Alert("server :: read error:", e)
			time.Sleep(time.Second)
			retryCount++
			if retryCount > 5 {
				retryCount = 0
				return
			}
		} else {
			logger.Debug("server :: read data ")
			if _this.isRunning {
				if _this.receiveEvent != nil {
					_this.receiveEvent(key, buffer[:length])
				}
			}
			retryCount = 0
		}
	}
}
